﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;

using System.Xml.Linq;

namespace AgileShare.Framework.SiteProvisioning.Definitions
{
	/// <summary>
	/// The configuration of a field that can be used to add a new field to SharePoint. The DefinitionXml property returns the field in a valid SharePoint XML format.
	/// </summary>
	/// <example>	
	/// FieldDefinition fieldDefinition = new FieldDefinition(new Guid("{F56D2B4F-242A-4169-89F9-F3CA0AB33E8A}"), "MyFieldName", "My Field Display Name", "My Field Description", true, "My Group");
	/// 
	/// SPFieldHelper.AddField(fieldDefinition, list.Fields); // Add to SPList fields
	/// SPFieldHelper.AddField(fieldDefinition, web.Fields); // Add to SPWeb fields
	/// </example>
	public class FieldDefinitionLookup : FieldDefinition
	{
		/// <summary>
		/// Gets or sets the lookup list id.
		/// </summary>
		/// <value>
		/// The lookup list id.
		/// </value>
		public Guid LookupListId { get; set; }

		/// <summary>
		/// Gets or sets the show field.
		/// </summary>
		/// <value>
		/// The show field.
		/// </value>
		public string ShowField { get; set; }

		/// <summary>
		/// Gets or sets the field ref.
		/// </summary>
		/// <value>
		/// The field ref.
		/// </value>
		public Guid? FieldRef { get; set; }

		/// <summary>
		/// Gets or sets a value indicating whether [prepend id].
		/// </summary>
		/// <value>
		///   <c>true</c> if [prepend id]; otherwise, <c>false</c>.
		/// </value>
		public bool PrependId { get; set; }

		/// <summary>
		/// Gets or sets a value indicating whether [allow multiple values].
		/// </summary>
		/// <value>
		///   <c>true</c> if [allow multiple values]; otherwise, <c>false</c>.
		/// </value>
		public bool AllowMultipleValues { get; set; }

		public FieldDefinitionLookup()
		{
			base.Type = this.AllowMultipleValues ? FieldType.LookupMulti : FieldType.Lookup;
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="FieldDefinitionLookup"/> class.
		/// </summary>
		/// <param name="id">The id.</param>
		/// <param name="name">The name.</param>
		/// <param name="displayName">The display name.</param>
		/// <param name="description">The description.</param>
		/// <param name="required">if set to <c>true</c> [required].</param>
		/// <param name="group">The group.</param>
		/// <param name="lookupListId">The lookup list id.</param>
		/// <param name="showField">The show field.</param>
		/// <param name="fieldRef">The field ref.</param>
		public FieldDefinitionLookup(Guid id, string name, string displayName, string description, bool required, string group, Guid lookupListId, string showField, bool allowMultipleValues, Guid? fieldRef, params object[] additionalData) :
			base(id, FieldType.Lookup, name, displayName, description, required, group, additionalData)
		{
			this.AllowMultipleValues = allowMultipleValues;
			if (this.AllowMultipleValues)
			{
				base.Type = FieldType.LookupMulti;
			}
			this.LookupListId = lookupListId;
			this.ShowField = showField;
			this.FieldRef = fieldRef;
		}

		public override FieldType Type
		{
			get
			{
				return this.AllowMultipleValues ? FieldType.LookupMulti : FieldType.Lookup;
			}
			set { }
		}

		/// <summary>
		/// Gets the definition XML.
		/// </summary>
		public override System.Xml.Linq.XElement DefinitionXml
		{
			get
			{
				base.Type = this.AllowMultipleValues ? FieldType.MultiChoice : FieldType.Choice;
				var field = base.DefinitionXml;

				field.Add(new XAttribute("List", this.LookupListId));
				AddAttributeIfNotNull(field, "ShowField", this.ShowField);
				if (this.FieldRef != null)
				{
					field.Add(new XAttribute("FieldRef", this.FieldRef));
					field.Add(new XAttribute("ReadOnly", bool.TrueString.ToUpper()));
				}
				if (this.AllowMultipleValues)
				{
					field.Add(new XAttribute("Mult", bool.TrueString.ToUpper()));
					field.Add(new XAttribute("PrependId", this.PrependId.ToString().ToUpper()));
				}

				return field;
			}
		}
	}
}
